<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JavaScript的原型继承</title>
</head>
<body>
<p>所有的数据都是对象</p>
<div id="div1"> 我是一个div1</div>
<script>
    let obj1 = new Object();
    let obj2 = {};
    console.log(Object.getPrototypeOf(obj1) === Object.prototype); // true
    console.log(Object.getPrototypeOf(obj2) === Object.prototype); // true

    // 实现bind
    Function.prototype.bind = function (context) {
        return () => this.apply(context, arguments)
    }

    // Function.prototype.call 和 Function.prototype.apply 可以动态改变this

    var obj3 = {
        name: 'sven',
        getName: function () {
            return this.name
        }
    }
    let obj4 = {
        name: 'anne'
    }

    console.log('obj3.getName.call(obj4);', obj3.getName.call(obj4))

    // 为什么不能用这种方法
    // let getId = document.getElementById;
    // console.log(getId('div1').apply(document))  // 报错
    // 因为 this 本来被期望指向document 如此一来就变成了指向Window

    // 使用apply帮助修正 this
    document.getElementById = (function (func) {
        return function () {
            return func.apply(document, arguments)
        }
    })(document.getElementById)

    let getId = document.getElementById;
    var div1 = getId('div1')
    console.log(div1)

    // call apply this

    // 第一个参数指定函数内部的this指向 第二个参数会作为函数的参数
    let func = function (...arg) {
        let [a, b, c] = arg
        console.log(a, b, c, 'abc')
    }
    func.apply(null, [1, 2, 33]);

    // 借用其他对象的方法

    let A = function (name) {
        this.name = name
    }
    let B = function () {
        A.apply(this, arguments)
    }
    let b = new B('a的名字')
    console.log('b,' , b)

// 模拟 Array.of 方法
    let MOCK_ARRAY_OF = function () {
        return [].slice.call(arguments)
    }

    console.log( MOCK_ARRAY_OF(1,2, 3))


    // 2

</script>
</body>
</html>